using System;
using System.Threading.Tasks;
using Admin.NET.Application.Entity.Business;
using Admin.NET.Application.Service.Bill.Dto;
using Admin.NET.Core;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace Admin.NET.Application.Service.Bill;

/// <summary>
/// 发票相关服务
/// </summary>
[ApiDescriptionSettings(new string[] { "业务应用" }, Order = 100)]
public class InvoiceService : IDynamicApiController, ITransient, IPrivateDependency
{
	private readonly UserManager _userManager;

	private readonly SqlSugarRepository<InvoiceManage> _rep;

	public InvoiceService(UserManager userManager, SqlSugarRepository<InvoiceManage> rep)
	{
		_userManager = userManager;
		_rep = rep;
	}

	/// <summary>
	/// 获取发票抬头列表
	/// </summary>
	/// <param name="page"></param>
	/// <param name="limit"></param>
	/// <returns></returns>
	[HttpGet("/invoice/titlelist")]
	public async Task<dynamic> GetTitleList(int page, int limit)
	{
		return await (from w in _rep.AsQueryable()
			where w.OwnerId == _userManager.UserId
			select w).ToPagedListAsync(page, limit);
	}

	/// <summary>
	/// 新增抬头
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/invoice/addtitle")]
	public async Task AddTitle(AddInvoiceInput input)
	{
		InvoiceManage entity = input.Adapt<InvoiceManage>();
		entity.OwnerId = _userManager.UserId;
		if (input.IsDefault)
		{
			await (from u in _rep.Context.Updateable<InvoiceManage>().SetColumns((InvoiceManage u) => u.IsDefault == false)
				where u.OwnerId == _userManager.UserId
				select u).ExecuteCommandAsync();
		}
		await _rep.InsertAsync(entity);
	}

	/// <summary>
	/// 更新抬头
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/invoice/updatetitle")]
	public async Task UpdateTitle(UpdateInvoiceInput input)
	{
		long ownerId = (await _rep.GetFirstAsync((InvoiceManage u) => u.Id == input.Id)).OwnerId;
		InvoiceManage entity = input.Adapt<InvoiceManage>();
		entity.OwnerId = ownerId;
		if (input.IsDefault)
		{
			await (from u in _rep.Context.Updateable<InvoiceManage>().SetColumns((InvoiceManage u) => u.IsDefault == false)
				where u.OwnerId == _userManager.UserId
				select u).ExecuteCommandAsync();
		}
		await _rep.UpdateAsync(entity);
	}

	/// <summary>
	/// 删除抬头
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/invoice/deletetitle")]
	public async Task DeleteTitle(DeleteInvoiceInput input)
	{
		InvoiceManage entity = await _rep.GetFirstAsync((InvoiceManage u) => u.Id == input.Id);
		await _rep.DeleteAsync(entity);
	}

	/// <summary>
	/// 设置默认抬头
	/// </summary>
	/// <param name="id"></param>
	/// <returns></returns>
	[HttpPost("/invoice/setdefaulttitle")]
	public async Task SetDefaultTitle([FromQuery] long id)
	{
		await (from u in _rep.Context.Updateable<InvoiceManage>().SetColumns((InvoiceManage u) => u.IsDefault == false)
			where u.OwnerId == _userManager.UserId
			select u).ExecuteCommandAsync();
		await (from u in _rep.Context.Updateable<InvoiceManage>().SetColumns((InvoiceManage u) => u.IsDefault == true)
			where u.OwnerId == _userManager.UserId && u.Id == id
			select u).ExecuteCommandAsync();
	}

	/// <summary>
	/// 获取发票抬头详情
	/// </summary>
	/// <param name="id"></param>
	/// <returns></returns>
	[HttpGet("/invoice/getinvociedetail")]
	public async Task<InvoiceManage> GetInvocieDetail([FromQuery] long id)
	{
		return await _rep.GetFirstAsync((InvoiceManage u) => u.Id == id);
	}

	/// <summary>
	/// 获取默认抬头
	/// </summary>
	/// <returns></returns>
	[HttpGet("/invoice/getdefaultinvocie")]
	public async Task<InvoiceManage> GetDefaultInvocie()
	{
		return await _rep.GetFirstAsync((InvoiceManage u) => u.IsDefault == true && u.OwnerId == _userManager.UserId);
	}

	/// <summary>
	/// 获取开票方名称
	/// </summary>
	/// <returns></returns>
	[HttpGet("/invoice/getapplyforname")]
	public async Task<string> GetApplyForName()
	{
		return await (from w in _rep.Context.Queryable<SysUser>()
			where w.TenantId == (long?)_userManager.TenantId && (int)w.AccountType == 888
			select w.RealName).FirstAsync();
	}

	/// <summary>
	/// 申请开票
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/invoice/applyforinvoice")]
	public async Task ApplyForInvoice(ApplyForInvoiceInput input)
	{
		ISqlSugarClient db = _rep.Context;
		try
		{
			await db.Ado.BeginTranAsync();
			if (input.RecordIds == null || input.RecordIds.Count == 0)
			{
				throw Oops.Bah("请先选择账单再进行申请开票");
			}
			if (await (from w in _rep.Context.Queryable<PaymentRecord>()
				where input.RecordIds.Contains(w.Id) && w.IsDrawABill != 0
				select w).CountAsync() > 0)
			{
				throw Oops.Bah("存在无效账单，请重新选择后申请");
			}
			BillRecord data = input.Adapt<BillRecord>();
			data.OwnerId = _userManager.UserId;
			await _rep.Context.Insertable(data).ExecuteCommandAsync();
			await (from u in _rep.Context.Updateable<PaymentRecord>().SetColumns((PaymentRecord u) => new PaymentRecord
				{
					IsDrawABill = 2,
					BillRecordId = data.Id
				})
				where u.OwnerId == (long?)_userManager.UserId && input.RecordIds.Contains(u.Id)
				select u).ExecuteCommandAsync();
			await db.Ado.CommitTranAsync();
		}
		catch (Exception ex)
		{
			await db.Ado.RollbackTranAsync();
			throw ex;
		}
	}

	/// <summary>
	/// 撤销申请
	/// </summary>
	/// <param name="id"></param>
	/// <returns></returns>
	[HttpPost("/invoice/cancelapplyforinvoice")]
	public async Task CancelApplyForInvoice([FromQuery] long id)
	{
		ISqlSugarClient db = _rep.Context;
		try
		{
			await db.Ado.BeginTranAsync();
			BillRecord data = await (from w in _rep.Context.Queryable<BillRecord>()
				where w.Id == id
				select w).FirstAsync();
			if (data == null)
			{
				throw Oops.Bah("该记录不存在或已被删除，请刷新后重试");
			}
			if (data.Status != 0)
			{
				throw Oops.Bah("该记录已被审核，无法撤销");
			}
			await (from u in _rep.Context.Updateable<BillRecord>().SetColumns((BillRecord u) => u.Status == 3)
				where u.Id == id
				select u).ExecuteCommandAsync();
			await (from u in _rep.Context.Updateable<PaymentRecord>().SetColumns((PaymentRecord u) => new PaymentRecord
				{
					IsDrawABill = 0,
					BillRecordId = null
				})
				where u.OwnerId == (long?)_userManager.UserId && u.BillRecordId == (long?)data.Id && data.RecordIds.Contains(u.Id)
				select u).ExecuteCommandAsync();
			await db.Ado.CommitTranAsync();
		}
		catch (Exception ex)
		{
			await db.Ado.RollbackTranAsync();
			throw ex;
		}
	}

	/// <summary>
	/// 获取发票申请记录列表（业主端）
	/// </summary>
	/// <param name="page"></param>
	/// <param name="limit"></param>
	/// <returns></returns>
	[HttpGet("/invoice/getownerbillrecords")]
	public async Task<dynamic> GetOwnerBillRecords(int page, int limit)
	{
		return await (from w in _rep.Context.Queryable<BillRecord>()
			where w.OwnerId == _userManager.UserId
			orderby w.CreateTime descending
			select w).ToPagedListAsync(page, limit);
	}

	/// <summary>
	/// 获取发票申请记录
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/invoice/getbillrecords")]
	public async Task<dynamic> GetBillRecords([FromQuery] BillRecordInput input)
	{
		ISugarQueryable<BillRecord> query = _rep.Context.Queryable<BillRecord>().WhereIF(!string.IsNullOrWhiteSpace(input.Title), (BillRecord u) => u.Title.Contains(input.Title)).WhereIF(!string.IsNullOrWhiteSpace(input.DutyParagraph), (BillRecord u) => u.DutyParagraph.Contains(input.DutyParagraph))
			.WhereIF(input.Status.HasValue, (BillRecord u) => (int?)u.Status == input.Status)
			.WhereIF(input.InvoicingBeginDate.HasValue && input.InvoicingEndDate.HasValue, (BillRecord u) => u.InvoicingDate >= input.InvoicingBeginDate && u.InvoicingDate <= input.InvoicingEndDate);
		query = query.OrderBuilder(input);
		return await query.ToPagedListAsync(input.Page, input.PageSize);
	}

	/// <summary>
	/// 审核发票申请
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/invoice/auditbillrecord")]
	public async Task AuditBillRecord(AuditBillRecordInput input)
	{
		ISqlSugarClient db = _rep.Context;
		try
		{
			await db.Ado.BeginTranAsync();
			BillRecord data = await (from w in _rep.Context.Queryable<BillRecord>()
				where w.Id == input.Id
				select w).FirstAsync();
			if (data == null)
			{
				throw Oops.Bah("发票申请记录无效，请刷新后重试");
			}
			if (data.Status != 0)
			{
				throw Oops.Bah("该记录无法审核，请刷新后重试");
			}
			await (from u in _rep.Context.Updateable<BillRecord>().SetColumns((BillRecord u) => new BillRecord
				{
					Status = input.Status,
					PdfUrl = input.PdfUrl,
					InvoicingDate = input.InvoicingDate,
					AuditRemark = input.Remark,
					AuditUserId = _userManager.UserId,
					AuditUserName = _userManager.RealName
				})
				where u.Id == input.Id
				select u).ExecuteCommandAsync();
			int isdrawABill = ((input.Status == 1) ? 1 : 0);
			await (from u in _rep.Context.Updateable<PaymentRecord>().SetColumns((PaymentRecord u) => new PaymentRecord
				{
					IsDrawABill = isdrawABill
				})
				where u.OwnerId == (long?)_userManager.UserId && u.BillRecordId == (long?)data.Id && data.RecordIds.Contains(u.Id)
				select u).ExecuteCommandAsync();
			await db.Ado.CommitTranAsync();
		}
		catch (Exception ex)
		{
			await db.Ado.RollbackTranAsync();
			throw ex;
		}
	}
}
